From : C.Dimitrakakis (MBGE4CD1@fs1.ee.man.ac.uk)
Subject : Reducing colors of a shape, with dithering.
Ok, this is the extendend version with dithering!
Rate and r2 are the rates of proportionality  of
dither colour usage. (How much % will be used for each colour)
Anyway, this is *not* the correct rate. It is just an estimate.
For a correct rate
if the dithering pair is represented by the points A,B in space
and point T represents the original color,
then find point C where AB and TC intersect, with TC being
perpendicular to AB, thus finding the ratio AC/BC

Altough that above gives you always the correct ratio,
this one is almost as good. (but not always),
but is a lot,lot faster.
So, take a look: 

*************************

SCREEN 11
sources = 4
targets = 8
depth = 16
RANDOMIZE TIMER
DIM r(sources), g(sources), b(sources)
DIM red(targets), green(targets), blue(targets)
DIM rd(targets), gd(targets), bd(targets)

'Setting up Initial colours

FOR n = 1 TO sources
   r(n) = INT(RND * depth)
   g(n) = INT(RND * depth)
   b(n) = INT(RND * depth)
   PRINT r(n), g(n), b(n)
NEXT n

PRINT "-------------------------------------"

'setting target colours
FOR n = 1 TO targets
   red(n) = INT(RND * depth)
   green(n) = INT(RND * depth)
   blue(n) = INT(RND * depth)
PRINT red(n), green(n), blue(n)
NEXT n

'remap colours
FOR m = 1 TO sources
   PRINT "Source", r(m), g(m), b(m)
   dd = -1
   sel = -1
      FOR n = 1 TO targets
         dr = red(n) - r(m)
         dg = green(n) - g(m)
         db = blue(n) - b(m)
         d = SQR(dr ^ 2 + dg ^ 2 + db ^ 2)
         'PRINT red(n), green(n), blue(n), d
         IF dd <> -1 THEN 'if there has been a previous selection
            IF d < dd THEN 'compare selections
               dd = d 'select new color if
               sel = n 'new target closer to source color
            END IF
         ELSE        'if there was no previous selection
            dd = d   'select new color
            sel = n
         END IF
   NEXT n
'show selected color
   PRINT "Target", red(sel), green(sel), blue(sel), dd

'create table for possible dithers

   FOR n = 1 TO targets
      rd(n) = (red(sel) + red(n)) / 2
      gd(n) = (green(sel) + green(n)) / 2
      bd(n) = (blue(sel) + blue(n)) / 2
   NEXT n
   
'find best dithering pair
   dd2 = -1
   sel2 = -1
   FOR n = 1 TO targets
         dr = rd(n) - r(m)
         dg = gd(n) - g(m)
         db = bd(n) - b(m)
         d = SQR(dr ^ 2 + dg ^ 2 + db ^ 2)
'         PRINT rd(n), gd(n), bd(n), d
         IF dd2 <> -1 THEN 'if there has been a previous selection
            IF d < dd2 THEN 'compare selections
               dd2 = d 'select new color if
               sel2 = n 'new target closer to source color
            END IF
         ELSE        'if there was no previous selection
            dd2 = d   'select new color
            sel2 = n
         END IF
   NEXT n
   PRINT "Target2", red(sel2), green(sel2), blue(sel2)
   PRINT "Average", rd(sel2), gd(sel2), bd(sel2), dd2
'Now, take a look at the distances
'to find the rate of proportionality
   rate = dd2 / dd
   PRINT "Rate: "; rate
'and that is the result of dithering
   r2 = (1 - rate)
'the dithered colour
   tr = red(sel) * rate + red(sel2) * r2
   tg = green(sel) * rate + green(sel2) * r2
   tb = blue(sel) * rate + blue(sel2) * r2
   dr = tr - r(m)
   dg = tg - g(m)
   db = tb - b(m)
'the distance of the dithered colour
   td = SQR(dr ^ 2 + dg ^ 2 + db ^ 2)
   PRINT "Dithered", tr, tg, tb, td
NEXT m